package fiuba.td.fabrica.model.entities;

import java.util.Collections;
import java.util.List;

import org.apache.log4j.Logger;

import fiuba.td.fabrica.model.beans.LineaProduccionBean;


/**
 * Laboratorio es el lugar donde se invierte dinero para descubrir nuevas lineas de produccion
 * Como clase es un singleton, debido a que solo podemos tener 1 laboratorio
 */
public class Laboratorio {
	private static Logger logger = Logger.getLogger(Laboratorio.class);
	
	private static Laboratorio INSTANCE = null;
	private double inversionAcumulada;
	private static final double MAXIMA_INVERSION_DIARIA = 50;

	private Laboratorio (){
		this.inversionAcumulada = 0.0;
	}
	 
    private synchronized static void createInstance() {
        if (INSTANCE == null) { 
            INSTANCE = new Laboratorio();
        }
    }
	 
    public static Laboratorio getInstance() {
        if (INSTANCE == null) createInstance();
        return INSTANCE;
    }
    
	public double getInversionAcumulada() {
		return inversionAcumulada;
	}

	public void setInversionAcumulada(double inversionAcumulada) {
		this.inversionAcumulada = inversionAcumulada;
	}

	/**
	 * Recibo las lineas de produccion y de las que no estan habilitadas, valido si puedo habilitar 
	 * alguna, de menor a mayor costo de inversion, por eso las ordeno.
	 * Si puedo habilitar una linea, la habilito y descuento de la inversion acumulada, el costo de inversion
	 * @param lineasProduccion son las lineas de produccion que se levantaron la primera vez del xml y 
	 * estan en memoria
	 */
	public void investigar(List<LineaProduccionBean> lineasProduccion){
		Collections.sort(lineasProduccion);
		
		for (LineaProduccionBean lineaProduccion : lineasProduccion){
			if (!lineaProduccion.isHabilitada()){
				
				 if (this.inversionAcumulada >= lineaProduccion.getInversion()) {
						lineaProduccion.habilitar();
						logger.info("Se habilito una nueva linea: " + lineaProduccion.toString());
						
						this.inversionAcumulada -= lineaProduccion.getInversion();
						break;
				}
			}
		}
	}
	
	/**
	 * Este metodo tiene que ser llamado al final del dia pasandole la inversion que se desea realizar
	 * Si la inversion es mayor a la maxima permitida, se invierte esa maxima y se devuelve la diferencia
	 * entre lo que se quiso invertir y lo que realmente se invirtio
	 * @param inversion inversion a realizar
	 * @return Lo que realmente se invirtio
	 */
	public double invertir (double inversion){
		double inversionReal = inversion > MAXIMA_INVERSION_DIARIA ? MAXIMA_INVERSION_DIARIA : inversion;
		this.inversionAcumulada += inversionReal;
		
		logger.info("Se invirtio $" + inversionReal + " en el laboratorio. Inversion acumulada: $" + this.inversionAcumulada + ".");
		return inversionReal;
	}
}
